package wfm.query;

import java.util.List;
import java.util.Vector;

import org.activiti.engine.HistoryService;
import org.activiti.engine.history.HistoricVariableInstance;
import org.activiti.engine.history.HistoricVariableInstanceQuery;
import org.activiti.engine.runtime.Execution;
import org.activiti.engine.task.Task;

import wfm.activiti.ActivitiManager;
import wfm.entities.User;

public class QueryDao {

	static ActivitiManager manager=null;
	
	
	public static void init(){
		manager=ActivitiManager.getInstance();
		manager.startEnginesAndServices();
	}
	
	
	public static List<Task> getAllTasks(){
		init();
		List<Task> tasks=manager.getTaskRuntimeService().createTaskQuery().list();
		return tasks;
		
	}
	
	public static List<Task> getAllTasksWithAssignee(String assignee){
		init();
		List<Task> tasks=manager.getTaskRuntimeService().createTaskQuery().taskAssignee(assignee).list();
		return tasks;
		
	}
	
	public static List<Execution> getAllMessageSendingEvents(String messageName){
		init();
		List<Execution> executions=manager.getRuntimeService().createExecutionQuery().messageEventSubscriptionName(messageName).list();
		List<Execution> notEnded=new Vector<Execution>();
		
		for(Execution exec : executions){
			if(!exec.isEnded() && !exec.isSuspended())
				notEnded.add(exec);
		}
		
		return notEnded;
		
	}

	
	public static List<Task> getAllTasksToProcessKey(String processDefinitionKey){
		init();
		List<Task> tasks=manager.getTaskRuntimeService().createTaskQuery().processDefinitionKey(processDefinitionKey).list();
		return tasks;
		
	}
	
	
	public static List<Task> getAllTasksWithOwner(String owner){
		init();
		List<Task> tasks=manager.getTaskRuntimeService().createTaskQuery().taskOwner(owner).list();
		return tasks;
		
	}
	
	
	public static List<Task> getAllTasksWithCandidateGroupAndNoAssignee(String candidateGroup){
		init();
		List<Task> tasks=manager.getTaskRuntimeService().createTaskQuery().taskCandidateGroup(candidateGroup).taskUnassigned().list();
		return tasks;
		
	}
	
	
	public static void setAssigneeToTask(Task t,String assignee){
		init();
		if(t!=null && assignee!=null){
			manager.getTaskRuntimeService().setAssignee(t.getId(), assignee);
			System.out.println("Assigned");
		}
		else
			throw new RuntimeException("Error assigning a Task not all values != null");
		
	}
	
	
	public static void unassignTask(Task t){
		init();
		if(t!=null){
			manager.getTaskRuntimeService().resolveTask(t.getId());
			//manager.getTaskRuntimeService().setAssignee(t.getId(), null);
			System.out.println("Unassigned");
		}
		else
			throw new RuntimeException("Error unassigning a Task not all values != null");
		
		
		
	}
	
	
	public static void saveVariableToProcessWithTask(Task t,String name,Object o){
		init();
		if(t!=null && name!=null){
			manager.getRuntimeService().setVariable(t.getExecutionId(), name, o);
		}
		else
			throw new RuntimeException("Error setting Instance to a Task not all values != null");
		
	}
	
	
	public static void saveVariableToProcessById(String instanceId,String name,Object o){
		init();
		if(instanceId!=null && name!=null){
			manager.getRuntimeService().setVariable(instanceId, name, o);
		}
		else
			throw new RuntimeException("Error setting Variable to a Instance not all values != null");
		
	}
	
	
	public static Object getVariableToProcessWithTask(Task t,String name){
		init();
		if(t!=null && name!=null){
			return manager.getRuntimeService().getVariable(t.getExecutionId(), name);
		}
		else
			throw new RuntimeException("Error setting Variable to a Task not all values != null");
		
	}
	
	public static Object getVariableToProcessWithExecutionId(String execId,String name){
		init();
		if(execId!=null && name!=null){
			return manager.getRuntimeService().getVariable(execId, name);
		}
		else
			throw new RuntimeException("Error setting Variable to a Task not all values != null");
		
	}
	
	public static Object getVariableToProcessById(String instanceId,String name){
		init();
		if(instanceId!=null && name!=null){
			return manager.getRuntimeService().getVariable(instanceId, name);
		}
		else
			throw new RuntimeException("Error setting Variable to a Task not all values != null");
		
	}
	
	public static void abortProcess(Task t){
		init();
		if(t!=null){
			manager.getRuntimeService().deleteProcessInstance(t.getExecutionId(), "Not needed anymore");
			//manager.getTaskRuntimeService().setAssignee(t.getId(), null);
			System.out.println("Deleted");
		}
		else
			throw new RuntimeException("Error aborting a Task not all values != null");
	}
	
	
	public static Task getTaskById(String id){
		init();
		if(id!=null){
			Task t=manager.getTaskRuntimeService().createTaskQuery().taskId(id).singleResult();
			return t;
		}
		else
			throw new RuntimeException("Task not found");
	}
	
	public static String getFormKey(Task t){
		init();
		if(t!=null && t.getId()!=null)
			return manager.getFormService().getTaskFormData(t.getId()).getFormKey();
		else
			return null;
	}
	
	public static String getFormKey(String taskId){
		init();
		if(taskId!=null)
			return manager.getFormService().getTaskFormData(taskId).getFormKey();
		else
			return null;
	}

	
	public static void messageReceveived(String msgName, String executionId){
		init();		
		manager.getRuntimeService().messageEventReceived(msgName,executionId);
	}
	
	public static Task getNextTaskAndSetAssignee(String processInstanceId,User user){
		List<Task> tasks = manager.getProcessEngine().getTaskService()
				.createTaskQuery().taskCandidateGroup(user.getUserGroup())
				.processInstanceId(processInstanceId).list();
		
		Task task=null;
		
		if (tasks.size() > 0) {
			// Get first task
			task = tasks.get(0);

			QueryDao.setAssigneeToTask(task, user.getName());
		}
		
		return task;
	}
	
	public static List<HistoricVariableInstance> getAllHistoricVariableInstances(String variableName){
		ActivitiManager manager = ActivitiManager.getInstance();
		manager.startEnginesAndServices();
		HistoryService service=manager.getHistoryService();
		HistoricVariableInstanceQuery query = service.createHistoricVariableInstanceQuery();
		
		return query.variableName(variableName).list();
	}
}
